package com.zrwl.poscloud.core.restapi.admin.baseInfo;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.zrwl.poscloud.base.entity.*;
import com.zrwl.poscloud.core.annotion.AuthorityVerify.AuthorityVerify;
import com.zrwl.poscloud.core.annotion.OperationLogger.OperationLogger;
import com.zrwl.poscloud.core.global.admin.DeptDataStatic;
import com.zrwl.poscloud.commons.exception.ThrowableUtils;
import com.zrwl.poscloud.commons.utils.*;
import com.zrwl.poscloud.commons.validator.group.Delete;
import com.zrwl.poscloud.commons.validator.group.GetList;
import com.zrwl.poscloud.commons.validator.group.Insert;
import com.zrwl.poscloud.commons.validator.group.Update;
import com.zrwl.poscloud.xo.mapper.CompanyMapper;
import com.zrwl.poscloud.xo.mapper.DeptMapper;
import com.zrwl.poscloud.xo.mapper.SysDictDataMapper;
import com.zrwl.poscloud.xo.service.*;
import com.zrwl.poscloud.xo.vo.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.*;

/**
 * 导入批次 controller api类
 *
 * @author 刘思童 AutoGenerate
 * @date 2021-11-02
 */
@RestController
@Api(value = "导入批次相关接口", tags = {"导入批次相关接口"})
@RequestMapping("/importBatch")
@Slf4j
public class ImportBatchRestApi {
    @Autowired
    private ImportBatchService importBatchService;
    @Autowired
    private AdminService adminService;
    @Autowired
    private ImportDetailService importDetailService;
    @Autowired
    private DeptService deptService;
    @Autowired
    private EmployeeService employeeService;
    @Autowired
    private CompanyService companyService;
    @Resource
    private CompanyMapper companyMapper;
    @Resource
    private DeptMapper deptMapper;
    @Autowired
    private CompanyDictDataService companyDictDataService;
    @Autowired
    private SysDictDataService sysDictDataService;
    @Autowired
    private DeptAdminRService deptAdminRService;

    @AuthorityVerify
    @ApiOperation(value = "获取导入批次列表", notes = "获取导入批次列表", response = String.class)
    @PostMapping("/getList")
    public String getList(@Validated({GetList.class}) @RequestBody ImportBatchVO importBatchVO, BindingResult result) {
        ThrowableUtils.checkParamArgument(result);
        log.info("获取导入批次列表: {}", importBatchVO);
        AdminVO adminVO = adminService.getMe();
        if (!adminVO.isCompany()) {
            return ResultUtil.errorWithMessage("仅商户用户支持此功能");
        }
        if (importBatchVO.getAdminUid() == null) {
            importBatchVO.setAdminUid(adminVO.getUid());
        }
        return ResultUtil.successWithData(importBatchService.getPageList(importBatchVO));
    }

    @AuthorityVerify
    @ApiOperation(value = "获取导入批次列表", notes = "获取导入批次列表", response = String.class)
    @PostMapping("/getAllList")
    public String getAllList(@Validated({GetList.class}) @RequestBody ImportBatchVO importBatchVO, BindingResult result) {
        ThrowableUtils.checkParamArgument(result);
        log.info("获取导入批次列表: {}", importBatchVO);
        return ResultUtil.successWithData(importBatchService.getAllList(importBatchVO));
    }

    @AuthorityVerify
    @OperationLogger(value = "新增导入批次")
    @ApiOperation(value = "新增导入批次", notes = "新增导入批次", response = String.class)
    @PostMapping("/add")
    public String add(@Validated({Insert.class}) @RequestBody ImportBatchVO importBatchVO, BindingResult result) {
        ThrowableUtils.checkParamArgument(result);
        log.info("新增导入批次: {}", importBatchVO);
        AdminVO adminVO = adminService.getMe();
        if (!adminVO.isCompany()) {
            return ResultUtil.errorWithMessage("仅商户用户支持此功能");
        }
        if (importBatchVO.getAdminUid() == null) {
            importBatchVO.setAdminUid(adminVO.getUid());
        }
        return importBatchService.add(importBatchVO);
    }

    @AuthorityVerify
    @OperationLogger(value = "修改导入批次")
    @ApiOperation(value = "修改导入批次", notes = "修改导入批次", response = String.class)
    @PostMapping("/edit")
    public String edit(@Validated({Update.class}) @RequestBody ImportBatchVO importBatchVO, BindingResult result) {
        ThrowableUtils.checkParamArgument(result);
        log.info("修改导入批次: {}", importBatchVO);
        return importBatchService.edit(importBatchVO);
    }

    @AuthorityVerify
    @OperationLogger(value = "删除导入批次")
    @ApiOperation(value = "删除导入批次", notes = "删除导入批次", response = String.class)
    @PostMapping("/delete")
    public String delete(@Validated({Delete.class}) @RequestBody ImportBatchVO importBatchVO, BindingResult result) {
        ThrowableUtils.checkParamArgument(result);
        log.info("删除导入批次: {}", importBatchVO);
        return importBatchService.delete(importBatchVO);
    }

    /**
     * @param file         Excel 文件
     * @param uid          批次ID
     * @param maxErrorData 最大错误数量
     * @return
     * @throws Exception
     */
    @AuthorityVerify
    @OperationLogger(value = "批量导入")
    @ApiOperation(value = "批量导入", notes = "批量导入", response = String.class)
    @PostMapping("/batchImport")
    public String batchImport(@RequestParam("file") List<MultipartFile> file, @RequestParam("uid") String uid, @RequestParam("maxErrorData") int maxErrorData) throws Exception {
        /**
         * 1 获取当前操作员和字典内容
         * 2 获取当前批次
         * 2.1 将批次的列配置图进行转换
         * 3 Excel解析并判重
         * 4遍历数据并进行校验
         * 4.1 行号判重判空
         * 4.2 获取条件信息
         * 4.3 数据校验
         * 4.3.1 赋值给明细表importDetailVO
         * 4.4 处理导入
         */
        //1获取当前操作员和字典内容
        AdminVO adminVO = adminService.getMe();
        if (!adminVO.isCompany()) {
            return ResultUtil.errorWithMessage("仅商户用户支持此功能");
        }
        List<CompanyDictData> payLevelList = JsonUtils.jsonToList(JsonUtils.objectToJson(companyDictDataService.getListByCompanyDictType("employee_pay_level", adminVO.getCompanyUid()).get("list")), CompanyDictData.class);
        List<SysDictData> cardTypeList = JsonUtils.jsonToList(JsonUtils.objectToJson(sysDictDataService.getListByDictType("card_type").get("list")), SysDictData.class);
        //2获取当前批次
        ImportBatch importBatch = importBatchService.getById(uid);//获取当前批次
        if (importBatch.getStatus() == 2) {
            return ResultUtil.errorWithMessage("该批次已导入完成");
        }
        //将批次的列配置图进行转换
        Map<String, String> columnConfigMap = JSONObject.parseObject(importBatch.getColumnConfig(), LinkedHashMap.class, Feature.OrderedField);//按序排列
        List<CompanyBusinessFeeConfig> feeConfigList = JSONArray.parseArray(importBatch.getParam(), CompanyBusinessFeeConfig.class);
        Map<String, DeptVO> deptRoleTreeEntity = deptAdminRService.getMyDeptRoleTreeEntity(adminVO.getCompanyUid(), adminVO.getUid());
        //3Excel解析并判重
        List<Map<String, String>> list = new ArrayList<>();
        Map<String, Object> certCodeSuccessCertMap = new HashMap<String, Object>();
        Map<String, Object> employeeCodeSuccessCertMap = new HashMap<String, Object>();
        Map<String, Object> lineNumberSuccessCertMap = new HashMap<String, Object>();
        Map<String, Object> deptSuccessCertMap = new HashMap<String, Object>();
        for (int i = 0; i < file.size(); i++) {
            MultipartFile fileO = file.get(i);
            if (fileO.isEmpty()) {
                continue;
            }
            list.addAll(ExcelUtil.ArrayList(file.get(i)));
        }

        List<ImportDetailVO> detailList = new LinkedList<>();//返回的错误数据
        //4遍历数据并进行校验
        for (int i = 0; i < list.size(); i++) {
            ImportDetailVO importDetailVO = new ImportDetailVO();
            importDetailVO.setBatchUid(uid);
            if (list.get(i).size() == 0) {
                continue;
            }

            Map<String, String> row = list.get(i);
            // 行号判重判空
            try {
                if (StringUtils.isEmpty(row.get("行号")) || StringUtils.isEmpty(row.get("行号").trim())) {
                    throw new RuntimeException("行号不可为空");
                }
                if (lineNumberSuccessCertMap.get(row.get("行号")) != null) {
                    throw new RuntimeException("行号重复-表内重复");
                }
                if (importDetailService.lineNumberVerify(importDetailVO.getBatchUid(), Integer.parseInt(row.get("行号")))) {
                    throw new RuntimeException("行号重复-数据库重复");
                }
                importDetailVO.setLineNumber(Integer.parseInt(row.get("行号")));
                lineNumberSuccessCertMap.put(row.get("行号"), row);
            } catch (RuntimeException e) {
                importDetailVO.setLineNumber(Integer.parseInt(row.get("行号")));
                importDetailVO.setSummary("失败原因 : " + e.getMessage());
                importDetailVO.setStatus(2);
            }
            //赋值给明细表importDetailVO
            for (Map.Entry<String, String> entry : columnConfigMap.entrySet()) {
                String name = null;
                if (entry.getValue().split(",").length > 1) {
                    for (String key : row.keySet()) {
                        if (entry.getValue().split(",")[0].equals(key.split("\\(")[0])) {
                            name = key;
                            break;
                        }
                    }
                } else {
                    name = entry.getValue();
                }
                //赋值给明细表importDetailVO
                if (StringUtils.isNotEmpty(row.get(name)) && StringUtils.isNotEmpty(row.get(name).trim())) {
                    ClassUtil.setFieldValueByFieldName(entry.getKey(), importDetailVO, row.get(name));
                }
            }

            ImportDetailVO detailVO = importDetailService.singleImport(columnConfigMap, feeConfigList, payLevelList, cardTypeList, importBatch, importDetailVO, adminVO, certCodeSuccessCertMap, employeeCodeSuccessCertMap,deptRoleTreeEntity,deptSuccessCertMap);
            importDetailVO = new ImportDetailVO();
            if (detailVO.getStatus() == 2) {
                detailList.add(detailVO);
            }
            if (detailList.size() >= maxErrorData) {
                break;
            }
        }
        return ResultUtil.successWithDataAndMessage(detailList, "成功导入" + (maxErrorData > list.size() ? (list.size() - detailList.size()) : (detailList.size() == 0 ? list.size() : (maxErrorData - detailList.size()))) + "条数据，失败" + detailList.size() + "条数据！");
    }
}
